home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / mach / ds3100.md / ioctl.c < prev    next >
C/C++ Source or Header  |  1991-08-05  |  16KB  |  600 lines

  1. /* 
  2.  * ioctl.c --
  3.  *
  4.  *    Procedure to map from Unix ioctl system call to Sprite.
  5.  *
  6.  * Copyright 1986 Regents of the University of California
  7.  * All rights reserved.
  8.  */
  9.  
  10. #ifndef lint
  11. static char rcsid[] = "$Header: /sprite/src/kernel/mach/ds3100.md/RCS/ioctl.c,v 9.4 90/09/21 15:51:39 mgbaker Exp $ SPRITE (Berkeley)";
  12. #endif not lint
  13.  
  14. #include "user/sys/ioctl.h"
  15. #include "user/sys/termios.h"
  16. #include "user/netEther.h"
  17. #include "sprite.h"
  18. #include "compatInt.h"
  19. #include "user/dev/tty.h"
  20. #include "user/dev/net.h"
  21. #include "user/dev/graphics.h"
  22. #include "fs.h"
  23. #include "errno.h"
  24.  
  25. #include "user/sys/types.h"
  26. #include "fcntl.h"
  27. #include "user/sys/socket.h"
  28. #include "user/sys/ttychars.h"
  29. #include "user/sys/ttydev.h"
  30. #include "user/net/route.h"
  31. #include "user/net/if.h"
  32. #include "user/sys/time.h"
  33. #include "machInt.h"
  34. #include "mach.h"
  35.  
  36. #ifdef __STDC__
  37. static void DecodeRequest _ARGS_((int request));
  38. #else
  39. #define const
  40. static void DecodeRequest();
  41. #endif
  42.  
  43. #ifdef notdef
  44. int compatTapeIOCMap[] = {
  45.     IOC_TAPE_WEOF,         /* 0, MTWEOF */
  46.     IOC_TAPE_SKIP_FILES,    /* 1, MTFSF */
  47.     IOC_TAPE_BACKUP_FILES,    /* 2, MTBSF */
  48.     IOC_TAPE_SKIP_BLOCKS,    /* 3, MTFSR */
  49.     IOC_TAPE_BACKUP_BLOCKS,    /* 4, MTBSR */
  50.     IOC_TAPE_REWIND,         /* 5, MTREW */
  51.     IOC_TAPE_OFFLINE,         /* 6, MTOFFL */
  52.     IOC_TAPE_NO_OP,        /* 7, MTNOP */
  53.     IOC_TAPE_RETENSION,        /* 8, MTRETEN */
  54.     IOC_TAPE_ERASE,        /* 9, MTERASE */
  55. };
  56. #endif
  57.  
  58. unsigned ifcBuf[16] = {
  59. 0x306573, 0x8011a4e0, 0x1, 0x0,
  60. 0x2, 0x21100110, 0x0, 0x0,
  61. 0x306f6c, 0x0, 0x0, 0xf5c0,
  62. 0x2, 0x0100007f, 0x0, 0x0,
  63. };
  64.  
  65.  
  66. /*
  67.  *----------------------------------------------------------------------
  68.  *
  69.  * ioctl --
  70.  *
  71.  *    Compat procedure for Unix ioctl call. This procedure usually does
  72.  *    nothing.
  73.  *
  74.  * Results:
  75.  *    Error code returned, SUCCESS if no error.
  76.  *
  77.  * Side effects:
  78.  *    None.
  79.  *
  80.  *----------------------------------------------------------------------
  81.  */
  82. int
  83. MachUNIXIoctl(fd, request, buf)
  84.     int        fd;
  85.     int        request;
  86.     char *    buf;
  87. {
  88.     ReturnStatus    status;
  89.     Address        usp;
  90.     extern Mach_State    *machCurStatePtr;
  91.  
  92.     usp = (Address)machCurStatePtr->userState.regState.regs[SP];
  93.     switch (request) {
  94.  
  95.     /*
  96.      * Generic calls:
  97.      */
  98.  
  99.     case FIOCLEX: {
  100.         /*
  101.          * Set the close-on-exec bit for the file.
  102.          * Buf is not used.
  103.          */
  104.  
  105.         int flag = IOC_CLOSE_ON_EXEC;
  106.         usp -= sizeof(flag);
  107.         status = Vm_CopyOut(sizeof(flag), (Address)&flag, usp);
  108.         if (status != SUCCESS) {
  109.             break;
  110.         }
  111.         status = Fs_IOControlStub(fd, IOC_SET_BITS, 
  112.                       sizeof(flag), usp, 0, (Address) NULL);
  113.         }
  114.         break;
  115.  
  116.     case FIONCLEX: {
  117.         /*
  118.          * Clear the close-on-exec bit for the file.
  119.          * Buf is not used.
  120.          */
  121.  
  122.         int flag = IOC_CLOSE_ON_EXEC;
  123.         usp -= sizeof(flag);
  124.         status = Vm_CopyOut(sizeof(flag), (Address)&flag, usp);
  125.         if (status != SUCCESS) {
  126.             break;
  127.         }
  128.         status = Fs_IOControlStub(fd, IOC_CLEAR_BITS, 
  129.                       sizeof(flag), usp, 0, (Address) NULL);
  130.         }
  131.         break;
  132.  
  133.     case FIONREAD:
  134.         status = Fs_IOControlStub(fd, IOC_NUM_READABLE, 0, (Address) NULL,
  135.                       sizeof(int), buf);
  136.         break;
  137.  
  138.         case FIONBIO: {
  139.         /*
  140.          * Set or clear the non-blocking I/O bit for the file.
  141.          */
  142.  
  143.         int flag = IOC_NON_BLOCKING;
  144.         int setBit;
  145.  
  146.         if (Vm_CopyIn(4, buf, &setBit) != SUCCESS) {
  147.             status = SYS_ARG_NOACCESS;
  148.             break;
  149.         }
  150.         usp -= sizeof(flag);
  151.         status = Vm_CopyOut(sizeof(flag), (Address)&flag, usp);
  152.         if (status != SUCCESS) {
  153.             break;
  154.         }
  155.         if (setBit) {
  156.             status = Fs_IOControlStub(fd, IOC_SET_BITS, 
  157.                 sizeof(flag), usp, 0, (Address) NULL);
  158.         } else {
  159.             status = Fs_IOControlStub(fd, IOC_CLEAR_BITS, 
  160.                 sizeof(flag), usp, 0, (Address) NULL);
  161.         }
  162.         }
  163.         break;
  164.  
  165.     case FIOASYNC: {
  166.         /*
  167.          * Set or clear the asynchronous I/O bit for the file.
  168.          */
  169.  
  170.         int flag = IOC_ASYNCHRONOUS;
  171.         int setBit;
  172.  
  173.         if (Vm_CopyIn(4, buf, &setBit) != SUCCESS) {
  174.             status = SYS_ARG_NOACCESS;
  175.             break;
  176.         }
  177.         usp -= sizeof(flag);
  178.         status = Vm_CopyOut(sizeof(flag), (Address)&flag, usp);
  179.         if (status != SUCCESS) {
  180.             break;
  181.         }
  182.         if (setBit) {
  183.             status = Fs_IOControlStub(fd, IOC_SET_BITS, 
  184.                 sizeof(flag), usp, 0, (Address) NULL);
  185.         } else {
  186.             status = Fs_IOControlStub(fd, IOC_CLEAR_BITS, 
  187.                 sizeof(flag), usp, 0, (Address) NULL);
  188.         }
  189.         }
  190.         break;
  191.  
  192.  
  193.     case FIOGETOWN:
  194.     case SIOCGPGRP:
  195.     case TIOCGPGRP: {
  196.         Ioc_Owner owner;
  197.  
  198.         usp -= sizeof(owner);
  199.         status = Fs_IOControlStub(fd, IOC_GET_OWNER, 0,
  200.                     (Address)NULL, sizeof(Ioc_Owner), usp);
  201.         if (status == SUCCESS) {
  202.             (void)Vm_CopyIn(sizeof(owner), usp, (Address)&owner);
  203.             status = Vm_CopyOut(sizeof(int), &owner.id, buf);
  204.         }
  205.         }
  206.         break;
  207.  
  208.     case FIOSETOWN:
  209.     case SIOCSPGRP:
  210.     case TIOCSPGRP: {
  211.         Ioc_Owner owner;
  212.  
  213.         status = Vm_CopyIn(sizeof(int), buf, &owner.id);
  214.         if (status != SUCCESS) {
  215.         break;
  216.         }
  217.         owner.procOrFamily = IOC_OWNER_FAMILY;
  218.         usp -= sizeof(owner);
  219.         status = Vm_CopyOut(sizeof(owner), (Address)&owner, usp);
  220.         if (status != SUCCESS) {
  221.         break;
  222.         }
  223.         status = Fs_IOControlStub(fd, IOC_SET_OWNER, sizeof(Ioc_Owner),
  224.                       usp, 0, (Address)NULL);
  225.         break;
  226.     }
  227.  
  228.     /* 
  229.      * Tty-related calls:
  230.      */
  231.  
  232.     case TIOCGETP:
  233.         status = Fs_IOControlStub(fd, IOC_TTY_GET_PARAMS, 0, (Address) NULL,
  234.             sizeof(struct sgttyb), (Address) buf);
  235.         break;
  236.     case TIOCSETP:
  237.         status = Fs_IOControlStub(fd, IOC_TTY_SET_PARAMS, sizeof(struct sgttyb),
  238.             (Address) buf, 0, (Address) NULL);
  239.         break;
  240.     case TIOCSETN:
  241.         status = Fs_IOControlStub(fd, IOC_TTY_SETN, sizeof(struct sgttyb),
  242.             (Address) buf, 0, (Address) NULL);
  243.         break;
  244.     case TIOCEXCL:
  245.         status = Fs_IOControlStub(fd, IOC_TTY_EXCL, 0, (Address) NULL,
  246.             0, (Address) NULL);
  247.         break;
  248.     case TIOCNXCL:
  249.         status = Fs_IOControlStub(fd, IOC_TTY_NXCL, 0, (Address) NULL,
  250.             0, (Address) NULL);
  251.         break;
  252.     case TIOCHPCL:
  253.         status = Fs_IOControlStub(fd, IOC_TTY_HUP_ON_CLOSE, 0,
  254.             (Address) NULL, 0, (Address) NULL);
  255.         break;
  256.     case TIOCFLUSH:
  257.         status = Fs_IOControlStub(fd, IOC_TTY_FLUSH, sizeof(int),
  258.             (Address) buf, 0, (Address) NULL);
  259.         break;
  260.     case TIOCSTI:
  261.         status = Fs_IOControlStub(fd, IOC_TTY_INSERT_CHAR, sizeof(char),
  262.             (Address) buf, 0, (Address) NULL);
  263.         break;
  264.     case TIOCSBRK:
  265.         status = Fs_IOControlStub(fd, IOC_TTY_SET_BREAK, 0,
  266.             (Address) NULL, 0, (Address) NULL);
  267.         break;
  268.     case TIOCCBRK:
  269.         status = Fs_IOControlStub(fd, IOC_TTY_CLEAR_BREAK, 0,
  270.             (Address) NULL, 0, (Address) NULL);
  271.         break;
  272.     case TIOCSDTR:
  273.         status = Fs_IOControlStub(fd, IOC_TTY_SET_DTR, 0, 
  274.             (Address) NULL, 0, (Address) NULL);
  275.         break;
  276.     case TIOCCDTR:
  277.         status = Fs_IOControlStub(fd, IOC_TTY_CLEAR_DTR, 0,
  278.             (Address) NULL, 0, (Address) NULL);
  279.         break;
  280.     case TIOCGETC:
  281.         status = Fs_IOControlStub(fd, IOC_TTY_GET_TCHARS, 0, (Address) NULL,
  282.             sizeof(struct tchars), (Address) buf);
  283.         break;
  284.     case TIOCSETC:
  285.         status = Fs_IOControlStub(fd, IOC_TTY_SET_TCHARS,
  286.             sizeof(struct tchars), (Address) buf, 0, (Address) NULL);
  287.         break;
  288.     case TIOCGLTC:
  289.         status = Fs_IOControlStub(fd, IOC_TTY_GET_LTCHARS, 0, (Address) NULL,
  290.             sizeof(struct ltchars), (Address) buf);
  291.         break;
  292.     case TIOCSLTC:
  293.         status = Fs_IOControlStub(fd, IOC_TTY_SET_LTCHARS,
  294.             sizeof(struct ltchars), (Address) buf, 0, (Address) NULL);
  295.         break;
  296.     case TIOCLBIS:
  297.         status = Fs_IOControlStub(fd, IOC_TTY_BIS_LM,
  298.             sizeof(int), (Address) buf, 0, (Address) NULL);
  299.         break;
  300.     case TIOCLBIC:
  301.         status = Fs_IOControlStub(fd, IOC_TTY_BIC_LM,
  302.             sizeof(int), (Address) buf, 0, (Address) NULL);
  303.         break;
  304.     case TIOCLSET:
  305.         status = Fs_IOControlStub(fd, IOC_TTY_SET_LM,
  306.             sizeof(int), (Address) buf, 0, (Address) NULL);
  307.         break;
  308.     case TIOCLGET:
  309.         status = Fs_IOControlStub(fd, IOC_TTY_GET_LM, 0, (Address) NULL,
  310.             sizeof(int), (Address) buf);
  311.         break;
  312.     case TIOCGETD:
  313.         status = Fs_IOControlStub(fd, IOC_TTY_GET_DISCIPLINE, 0,
  314.             (Address) NULL, sizeof(int), (Address) buf);
  315.         break;
  316.     case TIOCSETD:
  317.         status = Fs_IOControlStub(fd, IOC_TTY_SET_DISCIPLINE,
  318.         sizeof(int), (Address) buf, 0, (Address) NULL);
  319.         break;
  320.  
  321.     case SIOCATMARK:
  322.         status = Fs_IOControlStub(fd, IOC_NET_IS_OOB_DATA_NEXT,
  323.                 0, (Address) NULL, sizeof(int), (Address) buf);
  324.         break;
  325.  
  326.         case TCGETS:
  327.         status = Fs_IOControlStub(fd, IOC_TTY_GET_TERMIO,
  328.         0, (Address) NULL, sizeof(struct termios), (Address) buf);
  329.         break;
  330.  
  331.         case TCSETS:
  332.         status = Fs_IOControlStub(fd, IOC_TTY_SET_TERMIO,
  333.         sizeof(struct termios), (Address) buf, 0, (Address) NULL);
  334.         break;
  335.  
  336.     case TIOCGWINSZ:
  337.         status = Fs_IOControlStub(fd, IOC_TTY_GET_WINDOW_SIZE,
  338.         0, (Address) NULL, sizeof(struct winsize), (Address) buf);
  339.         break;
  340.  
  341.         case TIOCSWINSZ:
  342.         status = Fs_IOControlStub(fd, IOC_TTY_SET_WINDOW_SIZE,
  343.         sizeof(struct winsize), (Address) buf, 0, (Address) NULL);
  344.         break;
  345.     /*
  346.      * Graphics requests.
  347.      */
  348.     case QIOCGINFO:
  349.         status = Fs_IOControlStub(fd, IOC_GRAPHICS_GET_INFO,
  350.         0, (Address) NULL, sizeof(DevScreenInfo *), (Address)buf);
  351.         break;
  352.     case QIOCPMSTATE:
  353.         status = Fs_IOControlStub(fd, IOC_GRAPHICS_MOUSE_POS,
  354.         sizeof(DevCursor), (Address) buf, 0, (Address)NULL);
  355.         break;
  356.     case QIOWCURSORCOLOR:
  357.         status = Fs_IOControlStub(fd, IOC_GRAPHICS_CURSOR_COLOR,
  358.         sizeof(unsigned int [6]), (Address) buf, 0, (Address)NULL);
  359.         break;
  360.     case QIOCINIT:
  361.         status = Fs_IOControlStub(fd, IOC_GRAPHICS_INIT_SCREEN,
  362.         0, (Address) NULL, 0, (Address)NULL);
  363.         break;
  364.     case QIOCKPCMD:
  365.         status = Fs_IOControlStub(fd, IOC_GRAPHICS_KBD_CMD,
  366.         sizeof(DevKpCmd), (Address) buf, 0, (Address)NULL);
  367.         break;
  368.     case QIOCADDR:
  369.         status = Fs_IOControlStub(fd, IOC_GRAPHICS_GET_INFO_ADDR,
  370.         0, (Address) NULL, sizeof(DevScreenInfo *), (Address)buf);
  371.         break;
  372.     case QIOWCURSOR:
  373.         status = Fs_IOControlStub(fd, IOC_GRAPHICS_CURSOR_BIT_MAP,
  374.         sizeof(short[32]), (Address) buf, 0, (Address)NULL);
  375.         break;
  376.     case QIOKERNLOOP:
  377.         status = Fs_IOControlStub(fd, IOC_GRAPHICS_KERN_LOOP,
  378.         0, (Address) NULL, 0, (Address)NULL);
  379.         break;
  380.     case QIOKERNUNLOOP:
  381.         status = Fs_IOControlStub(fd, IOC_GRAPHICS_KERN_UNLOOP,
  382.         0, (Address) NULL, 0, (Address)NULL);
  383.         break;
  384.     case QIOVIDEOON:
  385.         status = Fs_IOControlStub(fd, IOC_GRAPHICS_VIDEO_ON,
  386.         0, (Address) NULL, 0, (Address)NULL);
  387.         break;
  388.     case QIOVIDEOOFF:
  389.         status = Fs_IOControlStub(fd, IOC_GRAPHICS_VIDEO_OFF,
  390.         0, (Address) NULL, 0, (Address)NULL);
  391.         break;
  392.     case QIOSETCMAP:
  393.         status = Fs_IOControlStub(fd, IOC_GRAPHICS_COLOR_MAP,
  394.         sizeof(DevColorMap), (Address) buf, 0, (Address)NULL);
  395.         break;
  396.     case SIOCGIFCONF: {
  397.         /*
  398.          * Fake the ifconfig ioctl.  This is a hack done for X.  
  399.          * A more general implementation is probably needed.
  400.          */
  401.         struct ifconf ifc;
  402.         struct ifreq   ifreq;
  403.         extern int      machHostID;
  404.         int          *intPtr;
  405.  
  406.         status = Vm_CopyIn(sizeof(struct ifconf), buf, (Address)&ifc);
  407.         if (status != SUCCESS) {
  408.         return(status);
  409.         }
  410.  
  411.         if (ifc.ifc_len < 32) {
  412.         status = SYS_INVALID_ARG;
  413.         break;
  414.         }
  415.         /*
  416.          * We give a length of 32 and put in the request buffer 
  417.          * the name ("se0"), followed by the family (AF_INET), 
  418.          * and finally our internet address.
  419.          */
  420.         ifc.ifc_len = 32;
  421.         strcpy(ifreq.ifr_name, "se0");
  422.         intPtr = (int *)&ifreq.ifr_ifru;
  423.         *intPtr = AF_INET;
  424.         *(intPtr + 1) = machHostID;
  425.  
  426.         status = Vm_CopyOut(sizeof(struct ifconf), (Address)&ifc, buf);
  427.         status = Vm_CopyOut(32, (Address)&ifreq,
  428.                 (Address)ifc.ifc_ifcu.ifcu_req);
  429.         break;
  430.     }
  431.  
  432.  
  433.     case SIOCRPHYSADDR: {
  434.         /* Get the ethernet address. */
  435.  
  436.         struct ifdevea *p;
  437. #if 1
  438.         Net_EtherAddress etherAddress;
  439.  
  440.         Mach_GetEtherAddress(ðerAddress);
  441.         p = (struct ifdevea *) buf;
  442.         p->default_pa[0] = p->current_pa[0] = etherAddress.byte1;
  443.         p->default_pa[1] = p->current_pa[1] = etherAddress.byte2;
  444.         p->default_pa[2] = p->current_pa[2] = etherAddress.byte3;
  445.         p->default_pa[3] = p->current_pa[3] = etherAddress.byte4;
  446.         p->default_pa[4] = p->current_pa[4] = etherAddress.byte5;
  447.         p->default_pa[5] = p->current_pa[5] = etherAddress.byte6;
  448. #else
  449.         /*
  450.          * Stuff with forgery's ether address for testing
  451.          * verilog.
  452.          */
  453.         p = (struct ifdevea *) buf;
  454.         p->default_pa[0] = p->current_pa[0] = 0x08;
  455.         p->default_pa[1] = p->current_pa[1] = 0x00;
  456.         p->default_pa[2] = p->current_pa[2] = 0x2b;
  457.         p->default_pa[3] = p->current_pa[3] = 0x10;
  458.         p->default_pa[4] = p->current_pa[4] = 0x75;
  459.         p->default_pa[5] = p->current_pa[5] = 0x24;
  460. #endif
  461.         status = SUCCESS;
  462.  
  463.         }
  464.         break;
  465.  
  466.     /*
  467.      * Unknown requests:
  468.      */
  469.  
  470.     default:
  471.         DecodeRequest(request);
  472.         status = SYS_INVALID_ARG;
  473.     }
  474.     return(status);
  475. }
  476.  
  477.  
  478.  
  479. /*
  480.  *----------------------------------------------------------------------
  481.  *
  482.  * DecodeRequest --
  483.  *
  484.  *    Takes a UNIX ioctl request and prints the name of the request
  485.  *    on the standard error file.
  486.  *
  487.  * Results:
  488.  *    None.
  489.  *
  490.  * Side effects:
  491.  *    None.
  492.  *
  493.  *----------------------------------------------------------------------
  494.  */
  495.  
  496. typedef struct {
  497.     char *name;
  498.     int     request;
  499. } RequestName;
  500.  
  501. static void
  502. DecodeRequest(request)
  503.     int request;
  504. {
  505.     register int i;
  506.     /*
  507.      * The following list contains all the ioctls in 
  508.      * /usr/include/sys/ioctl.h (SunOS 3.2), and
  509.      * /usr/include/sys/termios.h (SunOS 4.0).
  510.      */
  511.     const static RequestName mapping[] = {
  512.     {"TIOCGETD",    TIOCGETD},
  513.     {"TIOCSETD",    TIOCSETD},
  514.     {"TIOCHPCL",    TIOCHPCL},
  515.     {"TIOCMODG",    TIOCMODG},
  516.     {"TIOCMODS",    TIOCMODS},
  517.     {"TIOCGETP",    TIOCGETP},
  518.     {"TIOCSETP",    TIOCSETP},
  519.     {"TIOCSETN",    TIOCSETN},
  520.     {"TIOCEXCL",    TIOCEXCL},
  521.     {"TIOCNXCL",    TIOCNXCL},
  522.     {"TIOCFLUSH",    TIOCFLUSH},
  523.     {"TIOCSETC",    TIOCSETC},
  524.     {"TIOCGETC",    TIOCGETC},
  525.     {"TIOCLBIS",    TIOCLBIS},
  526.     {"TIOCLBIC",    TIOCLBIC},
  527.     {"TIOCLSET",    TIOCLSET},
  528.     {"TIOCLGET",    TIOCLGET},
  529.     {"TIOCSBRK",    TIOCSBRK},
  530.     {"TIOCCBRK",    TIOCCBRK},
  531.     {"TIOCSDTR",    TIOCSDTR},
  532.     {"TIOCCDTR",    TIOCCDTR},
  533.     {"TIOCSLTC",    TIOCSLTC},
  534.     {"TIOCGLTC",    TIOCGLTC},
  535.     {"TIOCOUTQ",    TIOCOUTQ},
  536.     {"TIOCSTI",    TIOCSTI},
  537.     {"TIOCNOTTY",    TIOCNOTTY},
  538.     {"TIOCPKT",    TIOCPKT},
  539.     {"TIOCSTOP",    TIOCSTOP},
  540.     {"TIOCSTART",    TIOCSTART},
  541.     {"TIOCMSET",    TIOCMSET},
  542.     {"TIOCMBIS",    TIOCMBIS},
  543.     {"TIOCMBIC",    TIOCMBIC},
  544.     {"TIOCMGET",    TIOCMGET},
  545.     {"TIOCREMOTE",    TIOCREMOTE},
  546.     {"TIOCGWINSZ",    TIOCGWINSZ},
  547.     {"TIOCSWINSZ",    TIOCSWINSZ},
  548.     {"TIOCUCNTL",    TIOCUCNTL},
  549.     {"TIOCCONS",    TIOCCONS},
  550.     {"TIOCSSIZE",    TIOCSSIZE},
  551.     {"TIOCGSIZE",    TIOCGSIZE},
  552.     {"SIOCSHIWAT",    SIOCSHIWAT},
  553.     {"SIOCGHIWAT",    SIOCGHIWAT},
  554.     {"SIOCSLOWAT",    SIOCSLOWAT},
  555.     {"SIOCGLOWAT",    SIOCGLOWAT},
  556.     {"SIOCADDRT",    SIOCADDRT},
  557.     {"SIOCDELRT",    SIOCDELRT},
  558.     {"SIOCSIFADDR",    SIOCSIFADDR},
  559.     {"SIOCGIFADDR",    SIOCGIFADDR},
  560.     {"SIOCSIFDSTADDR",    SIOCSIFDSTADDR},
  561.     {"SIOCGIFDSTADDR",    SIOCGIFDSTADDR},
  562.     {"SIOCSIFFLAGS",    SIOCSIFFLAGS},
  563.     {"SIOCGIFFLAGS",    SIOCGIFFLAGS},
  564.     {"SIOCGIFCONF",    SIOCGIFCONF},
  565.     {"SIOCGIFBRDADDR",    SIOCGIFBRDADDR},
  566.     {"SIOCSIFBRDADDR",    SIOCSIFBRDADDR},
  567.     {"SIOCGIFNETMASK",    SIOCGIFNETMASK},
  568.     {"SIOCSIFNETMASK",    SIOCSIFNETMASK},
  569.     {"SIOCGIFMETRIC",    SIOCGIFMETRIC},
  570.     {"SIOCSIFMETRIC",    SIOCSIFMETRIC},
  571.     {"SIOCSARP",    SIOCSARP},
  572.     {"SIOCGARP",    SIOCGARP},
  573.     {"SIOCDARP",    SIOCDARP},
  574.     {"TCXONC",      TCXONC},
  575.     {"TCFLSH",      TCFLSH},
  576.     {"TCGETS",      TCGETS},
  577.     {"TCSETS",      TCSETS},
  578.     };
  579.  
  580.     if ((request == TIOCGSIZE) || (request == TIOCGWINSZ)) {
  581.     /*
  582.      * Special-case TIOCGSIZE since every visually-oriented program
  583.      * uses it and it's annoying to constantly get the messages.
  584.      */
  585.     return;
  586.     }
  587.  
  588.     /*
  589.      * For now search the list linearly. It's slow but simple...
  590.      */
  591.     for (i = sizeof(mapping)/sizeof(*mapping) - 1; i >= 0; --i) {
  592.     if (request == mapping[i].request) {
  593.         printf("ioctl: bad command %s\n", mapping[i].name);
  594.         return;
  595.     }
  596.     }
  597.     printf("ioctl: bad command 0x%x\n", request);
  598.     return;
  599. }
  600.